package com.lcykcl.ttgen;


import java.util.ArrayList;
import java.util.HashMap;
import android.os.Bundle;
import android.app.ActionBar.LayoutParams;
import android.app.Activity;
import android.content.Intent;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.Button;
import android.widget.RelativeLayout;
//Try to use two layouts! 
public class TimetableActivity extends Activity {

	private float d;
	private RelativeLayout MC;
	private RelativeLayout TC;
	private RelativeLayout WC;
	private RelativeLayout RC;
	private RelativeLayout FC;
	private HashMap<String, ArrayList<Button>> timeMap;
	private HashMap<String, ArrayList<Button>> siblingMap;
	private HashMap<String, ArrayList<Node>> CoursesMap;
	private Manager timetableManager;
	private static final HashMap<String, Persona> PERSONA_MAP = new HashMap<String, Persona>(){{
		put("Evenly Spread", Persona.EVEN);
		put("Packed", Persona.PACKED);
		put("Morning", Persona.MORNING);
		put("Night", Persona.NIGHT);
	}};
	

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		//super.onCreate(savedInstanceState);
		super.onCreate(null); // later it will be changed to super.onCreate(saved..)
		setContentView(R.layout.activity_timetable);
		
		Intent intent = getIntent();
		
		// nodes for lecture and tutorials for F semester
		@SuppressWarnings("unchecked")
		ArrayList<ArrayList<Node>> FNodes = (ArrayList<ArrayList<Node>>) intent.getSerializableExtra(MainActivity.F_NODES);
		// nodes for lecture and tutorials for S semester
		@SuppressWarnings("unchecked")
		ArrayList<ArrayList<Node>> SNodes = (ArrayList<ArrayList<Node>>) intent.getSerializableExtra(MainActivity.S_NODES);
        
        //selectedPersona is the persona that is check-boxed in the MainActivity by the user. 
        // it is 1 of the 4 following Strings: "Evenly Spread", "Packed", "Morning", "Night".
        String selectedPersona = intent.getStringExtra(MainActivity.PERSONA_SELECTED);
        Persona p = PERSONA_MAP.get(selectedPersona);
        
        timetableManager = new Manager(FNodes, SNodes, p);
        timetableManager.generateCompleteTimeTable();
       // HashMap<String, ArrayList<Node>> fallSiblingMap = timetableManager.getFallSiblingMap();
        HashMap<String, ArrayList<Node>> springSiblingMap = timetableManager.getSpringSiblingMap();
        ArrayList<Node> fallTimetable = timetableManager.getFallTimeTable();
        ArrayList<Node> springTimetable = timetableManager.getSpringTimeTable();
        
		this.d = this.getResources().getDisplayMetrics().density;
		this.MC = (RelativeLayout) findViewById(R.id.MonCol);
		this.TC = (RelativeLayout) findViewById(R.id.TueCol);
		this.WC = (RelativeLayout) findViewById(R.id.WedCol);
		this.RC = (RelativeLayout) findViewById(R.id.ThuCol);
		this.FC = (RelativeLayout) findViewById(R.id.FriCol);
		timeMap = new HashMap<String, ArrayList<Button>>();
		siblingMap = new HashMap<String, ArrayList<Button>>();
		CoursesMap =  timetableManager.getFallSiblingMap();

		//Need to set courseMap and courseList for setButtons For All
		setButtonsForAll(fallTimetable);


	}
	

	 //---Options Menu---
   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
       getMenuInflater().inflate(R.menu.options_timetable, menu);
       return true;
   }

   public void onSpringClicked() {
   	Intent intent  = new Intent(TimetableActivity.this,SpringSemester.class);     
		//intent.putExtra("springSiblingMap", CoursesMap);      
		startActivity(intent);
   }

   @Override
   public boolean onOptionsItemSelected(MenuItem item)
   {
       switch (item.getItemId()) {
       //case R.id.search_main:
           //startSearch(null);
           //return true;
       case R.id.button_fall:
           return true;
       case R.id.button_spring:
       	onSpringClicked();
           return true;
       default:
           return super.onOptionsItemSelected(item);
       }
   }
	


	public Boolean isConflict(ArrayList<String> timeList) {
		
		String day = timeList.get(0);
		String AMorPM = timeList.get(1);
		
		for (int i = 2; i < timeList.size(); i++) {
			String time = day + timeList.get(i) + AMorPM; //M1pm
			if (this.timeMap.containsKey(time) && this.timeMap.get(time).size() >= 1) {
				return true;
			}
		}
		return false;
	}

	// T1-3
	public String AmorPm(String time) {
		int endIndexOfstartTime = time.indexOf("-");
		//e.g., M1 then endIndexOfstartTime is 2. 
		if (endIndexOfstartTime == -1) {
			endIndexOfstartTime = time.length();
		}
		int start = Integer.valueOf(time.substring(1, endIndexOfstartTime));
		if (start <= 8 || start == 12) {
			return "pm"; //1,2,3,4,5,6,7,8,12
		} else {
			return "am"; //9,10,11
		}

	}

	public int getTopMargin(String time) {
		int startTime = Integer.valueOf(time);
		if (startTime >= 9 && startTime <= 12) { //where start time is 9, 10, 11, 12
			return 40 * (startTime - 8);
		} else {   
			return 40 * (startTime + 4);
		}
	}


	public void addButton(String courseName, Button bt) {
		if (siblingMap.containsKey(courseName)) {
			siblingMap.get(courseName).add(bt);
		} else {
			ArrayList<Button> button = new ArrayList<Button>();
			button.add(bt);
			siblingMap.put(courseName, button);
		}

	}

	public void addTime(ArrayList<String> timeList, Button bt) {
		String day = timeList.get(0);
		String AMorPM = timeList.get(1);
		String time ="";
		for (int i = 2; i < timeList.size(); i++) {
				time = day + timeList.get(i) + AMorPM;
			if (timeMap.containsKey(time)) {
				timeMap.get(time).add(bt);
			} else {
				ArrayList<Button> button = new ArrayList<Button>();
				button.add(bt);
				timeMap.put(time, button);
			}
		}
	}

	public ArrayList<String> getTimeList(String time) {
		//example of time : M1-2, R2 etc...
		// example of expected result: {"W", "pm", "1","2",} for M1-2
		//add day
		ArrayList<String> timeList = new ArrayList<String>();
		timeList.add(Character.toString(time.charAt(0)));
		//add am or pm
		int endOfstartTime = time.indexOf("-");
		if (endOfstartTime == -1) {
			endOfstartTime = time.length();
		}
		int start = Integer.valueOf(time.substring(1, endOfstartTime));
		timeList.add(AmorPm(time));

		// e.g, time = W3-6
		if (time.length() > 3) {
			int end = Integer.valueOf(time.substring(endOfstartTime + 1, time.length()));
			for (int i = start; i < end; i++) {
				timeList.add(Integer.toString(i));
			}
		} else {
			timeList.add(Integer.toString(start));
		}
		return timeList;
	}

	public void setButtonsForOne(Node course, int index) {
		// An example of course: {"csc236", "BA1201", "M1", "T1"}
		// index is the index of the course in the list which is the value of courseMap
		ArrayList<String> courseArray = course.toStringArray();
	
		String ButtonText = courseArray.get(0); 
		String lecturePlace = courseArray.get(1);
		String courseName = ButtonText;
		
		
		for (int i = 2; i < courseArray.size(); i++) {
			String time = courseArray.get(i);
			ArrayList<String> timeList = getTimeList(time);
			if (isConflict(timeList)) {
				ButtonText = "conflict";
			} else {
				ButtonText = courseName + "\n" + lecturePlace;
			}
			int topMargin = getTopMargin(timeList.get(2));
			int duration = (int) ((timeList.size() - 2) * 40 * this.d);
			String day = timeList.get(0);
			char day1 = day.charAt(0);
			Button bt = new Button(this);
			
			bt.setTag(courseName);
			bt.setId(index);
			
			registerForContextMenu(bt);

			bt.setPadding(0, 0, 0, 0);
			bt.setText(ButtonText);
			bt.setTextSize(10);
			
			RelativeLayout.LayoutParams pr = new RelativeLayout.LayoutParams(
					LayoutParams.MATCH_PARENT, duration);
			int margin = (int) (topMargin * this.d);
			pr.topMargin = margin;
			
			// add it to sibling dictionary
			addButton(courseName, bt);
			// add it to time dictionary
			addTime(timeList, bt);
			
			switch (day1) {
			case 'M':
				this.MC.addView(bt, pr);
				break;
			case 'T':
				this.TC.addView(bt, pr);
				break;
			case 'W':

				this.WC.addView(bt, pr);
				break;
			case 'R':

				this.RC.addView(bt, pr);
				break;
			case 'F':

				this.FC.addView(bt, pr);
				break;

			default:
				break;
			}
		}
	}

	
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);
		
		String courseName = ((String) ((Button)v).getTag());
		int index = v.getId();
		
		menu.setHeaderTitle(courseName);
		SubMenu alternatives = menu.addSubMenu(0, index, 0, "Show Alternatives of "
				+ courseName);
		popUpAlternatives(alternatives, courseName, index);
		menu.add(2, index, 0, "Remove " + courseName);
	}

	private void popUpAlternatives(SubMenu menu, String courseName, int index) {
		ArrayList<Node> course = this.CoursesMap.get(courseName);
		//An example of course:
		//{{ "csc236","BA1201", "M3", "T1" }, {"csc236","BA1201", "M1", "R2"}, {"csc236","BA1201", "T3", "R3"},
		//{"csc236","BA1201", "M1", "T6"}};
		
		for (int i = 0; i < course.size(); i++) {
			Node oneSection = course.get(i);
			ArrayList<String> oneSectionArray = oneSection.toStringArray();
			String description = oneSectionArray.get(0) + ": " + oneSectionArray.get(2);
			
			if(oneSectionArray.size() > 3){
				for (int j = 3; j < oneSectionArray.size(); j++) {
					description = description + ", " + oneSectionArray.get(j);
				}
			}
			menu.add(1, index, i, description);
		}
	}
	
	//From here!!!!!!!!!!!
	@Override
	public boolean onContextItemSelected(MenuItem item) {

		int selectedGroupID = item.getGroupId();
		int selectedItemID = item.getItemId();
		int index = item.getOrder();
		int length = item.getTitle().length();
		
		String courseName ="";
		
		if (selectedGroupID == 1) {
			courseName =  ((String) item.getTitle()).substring(0,6);
			ArrayList<Node> alternatives = this.CoursesMap.get(courseName);
			Node alternative = alternatives.get(index);
			remove(courseName, selectedItemID);
			setButtonsForOne(alternative, index);
		} else if (selectedGroupID == 2) {
				courseName = ((String) item.getTitle()).substring(length - 6,
						length);
				remove(courseName, selectedItemID);
		} else {
			return false;
		}
		return true;
	}

	private void remove(String courseName, int selectedButtonID) {
		
		ArrayList<Button> btList = this.siblingMap.get(courseName);
		
		for (int i = 0; i < btList.size(); i++) {
			((RelativeLayout) btList.get(i).getParent()).removeView(btList
					.get(i));
		}
		this.siblingMap.put(courseName, new ArrayList<Button>());
		updateTimeMap(this.CoursesMap.get(courseName).get(selectedButtonID).toStringArray(), courseName);
	}

	private void updateTimeMap(ArrayList<String> courseList, String courseName) {
		for (int i = 2; i < courseList.size(); i++) {
			ArrayList<String> timeList = getTimeList(courseList.get(i));
			String day = timeList.get(0);
			String AMorPM = timeList.get(1);
			for (int j = 2; j < timeList.size(); j++) {
				String time = day + timeList.get(j)+ AMorPM;
				ArrayList <Button> btList = this.timeMap.get(time);
				for (int k = 0; k < btList.size(); k++) {
					String course = ((String)btList.get(k).getTag());
					if (course.equalsIgnoreCase(courseName)) {
						btList.remove(k);
					}
				}
				if (btList.size() == 1) {
					Button btTochange = btList.get(0);
					String course = (String)btTochange.getTag();
					Integer courseIndex = btTochange.getId();
					ArrayList<String> cList = this.CoursesMap.get(course).get(courseIndex).toStringArray();
					btTochange.setText(course + "\n" + cList.get(1)); 
					btTochange.setTextSize(10);
				}
			}
		}
		
	}



	public void setButtonsForAll(ArrayList<Node> courses) {
		for (int i = 0; i < courses.size(); i++) {
			Node course = courses.get(i);
			setButtonsForOne(course, 0);
		}
	}
}

// Problem so far:

// 4. release conflict if one thing that overlapped disappeared
// 5. if I clicked "conflict", I should be able to handle it
// change save instance bundle on create from the null
